package com.example.common.recycler.base;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;

import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;

import com.example.common.recycler.common.RecyclerViewHolder;

import java.util.ArrayList;
import java.util.List;

/**
 * @param <T>  item对应的bean类
 * @param <VH> item对应的ViewHolder
 */
public abstract class BaseRecyclerAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
    public static final String FLAG_LOCAL_REFRESH = "FLAG_LOCAL_REFRESH";//局部刷新的标记，例如notifyItemChanged(1,BaseRecyclerAdapter.FLAG_LOCAL_REFRESH)

    public interface OnItemClickListener<T> {
        void onItemClick(View v, int position, T t);
    }

    public interface OnItemLongClickListener<T> {
        boolean onItemLongClick(View v, int position, T t);
    }

    private OnItemClickListener<T> mOnItemClickLitener;
    private OnItemLongClickListener<T> mOnItemLongClickLitener;

    //todo：如果不希望mList遭到外部修改，需要使用Collections.unmodifiableList
    protected List<T> mItems = new ArrayList();
    protected T mSelectedItem;//当前选中项，如无选中则为null
    private View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mOnItemClickLitener == null) {
                return;
            }
            if (v.getTag() == null) {
                return;
            }
            if (!(v.getTag() instanceof RecyclerView.ViewHolder)) {
                return;
            }
            RecyclerView.ViewHolder holder = ((RecyclerView.ViewHolder) v.getTag());
            int pos = holder.getAdapterPosition();
            mOnItemClickLitener.onItemClick(holder.itemView, pos, getItem(pos));
        }
    };

    private View.OnLongClickListener onLongClickListener = new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            if (mOnItemLongClickLitener == null) {
                return false;
            }
            if (v.getTag() == null) {
                return false;
            }
            if (!(v.getTag() instanceof  RecyclerView.ViewHolder)) {
                return false;
            }
            RecyclerView.ViewHolder holder = (( RecyclerView.ViewHolder) v.getTag());
            int pos = holder.getAdapterPosition();
            return mOnItemLongClickLitener.onItemLongClick(holder.itemView, pos, getItem(pos));
        }
    };

    @Override
    public int getItemCount() {
        return mItems == null ? 0 : mItems.size();
    }

    @Override
    public void onBindViewHolder(@NonNull VH holder, int position) {
        //ignore
    }

    @CallSuper
    @Override
    public void onBindViewHolder(@NonNull VH holder, int position, @NonNull List<Object> payloads) {
        bindItemClickListener(holder);
    }

    /**
     * 为itemview绑定监听器
     *
     * @param holder
     */
    public void bindItemClickListener(@NonNull final VH holder) {
        if (mOnItemClickLitener != null) {
            holder.itemView.setTag(holder);
            holder.itemView.setOnClickListener(onClickListener);
        }
        if (mOnItemLongClickLitener != null) {
            holder.itemView.setTag(holder);
            holder.itemView.setOnLongClickListener(onLongClickListener);
        }
    }

    /**
     * 获得LayoutInflater
     *
     * @param context
     * @return
     */
    public LayoutInflater getLayoutInflater(@NonNull Context context) {
        return (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }


    //****************************************扩展方法***************************************
    //开放以下方法便于用户使用

    /**
     * 设置监听器
     *
     * @param onItemClickLitener
     */
    public void setOnItemClickLitener(OnItemClickListener<T> onItemClickLitener) {
        this.mOnItemClickLitener = onItemClickLitener;
    }

    /**
     * 设置监听器
     *
     * @param onItemLongClickLitener
     */
    public void setOnItemLongClickListener(OnItemLongClickListener<T> onItemLongClickLitener) {
        this.mOnItemLongClickLitener = onItemLongClickLitener;
    }

    /**
     * 设置当前选中item
     *
     * @param item
     */
    public void setSelectedItem(T item) {
        this.mSelectedItem = item;
    }

    /**
     * 获得当前选中item
     *
     * @return
     */
    @Nullable
    public T getSelectedItem() {
        return this.mSelectedItem;
    }

    /**
     * 获得当前选中item在列表中的位置，从0开始
     *
     * @return -1表示找不到
     */
    public int getSelectedItemPosition() {
        if (mItems == null) {
            return -1;
        }
        T item = getSelectedItem();
        if (item == null) {
            return -1;
        }
        return mItems.indexOf(item);
    }

    /**
     * 获得指定位置的item数据
     *
     * @param position
     * @return
     */
    @Nullable
    public T getItem(int position) {
        try {
            return mItems.get(position);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获得item在列表中的位置
     *
     * @param item
     * @return -1表示找不到
     */
    public int getItemPosition(@NonNull T item) {
        int pos = -1;
        try {
            pos = mItems.indexOf(item);
        } catch (Exception ignore) {
        }
        return pos;
    }

    /**
     * 滑动到选中位置
     *
     * @param recyclerView
     */
    public void smoothScrollToSelectedPosition(@NonNull RecyclerView recyclerView) {
        if (recyclerView == null) {
            return;
        }
        int position = getSelectedItemPosition();
        if (position != -1) {
            recyclerView.smoothScrollToPosition(position);
        }
    }

    /**
     * 滑动到底部
     *
     * @param recyclerView
     */
    public void smoothScrollToBottom(@NonNull RecyclerView recyclerView) {
        if (recyclerView == null) {
            return;
        }
        int position = getItemCount() - 1;
        if (position != -1) {
            recyclerView.smoothScrollToPosition(position);
        }
    }

    /**
     * 是否已经滑动到底部
     * @param recyclerView
     * @return
     */
    public boolean isScrollToBottom(@NonNull RecyclerView recyclerView) {
        return !recyclerView.canScrollVertically(1);
    }

    /**
     * 是否已经滑动到顶部
     * @param recyclerView
     * @return
     */
    public boolean isScrollToTop(@NonNull RecyclerView recyclerView) {
        return !recyclerView.canScrollVertically(-1);
    }

    //--------------------------------------数据操作接口------------------------------------------------------

    /**
     * 添加数据（不清空旧数据）同时自动刷新
     *
     * @param list
     */
    public void addItems(@NonNull List<T> list) {
        addItems(list, false, false);
    }

    /**
     * 添加数据，同时自动刷新
     *
     * @param list
     * @param isClearOld 是否清空旧数据
     */
    public void addItems(@NonNull List<T> list, boolean isClearOld) {
        addItems(list, isClearOld, false);
    }

    /**
     * 添加数据
     *
     * @param list
     * @param isClearOld
     * @param isNotifyDataSetChanged
     */
    public void addItems(@NonNull List<T> list, boolean isClearOld, boolean isNotifyDataSetChanged) {
        if (isClearOld) {
            this.mItems.clear();
        }
        this.mItems.addAll(list);
        if (isNotifyDataSetChanged) {
            notifyDataSetChanged();
        }
    }

    /**
     * 添加数据到前面
     *
     * @param list
     */
    public void addItemsToFront(@NonNull List<T> list) {
        this.mItems.addAll(0, list);
    }

    /**
     * 添加数据到前面
     *
     * @param t
     */
    public void addItemToFront(@NonNull T t) {
        this.mItems.add(0, t);
    }

    /**
     * 添加数据
     *
     * @param t
     */
    public void addItem(@NonNull T t) {
        this.mItems.add(t);
    }

    /**
     * 添加数据
     *
     * @param t
     */
    public void addItem(int index, @NonNull T t) {
        this.mItems.add(index, t);
    }

    /**
     * 清空数据
     */
    public void clearItems() {
        this.mItems.clear();
    }

    /**
     * 获取数据
     *
     * @return
     */
    public List<T> getItems() {
        //fixme:此处应该使用Collections.unmodifiableList来返回一个不可修改的视图数据
        return this.mItems;
    }

    /**
     * 获取数据
     *
     * @return
     */
    public void setItems(@NonNull List<T> items) {
        if (items == null) {
            return;
        }
        this.mItems = items;
    }
}
